#!/usr/bin/perl
#
#   Copyright 2009 Enilsson Asia Pacific http://www.enilsson.com
#
#   This file is part of Sphinx real time live updates.
#   Sphinx real time live updates is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
#   Sphinx real time live updates is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#   You should have received a copy of the GNU General Public License along with Sphinx real time live updates. If not, see http://www.gnu.org/licenses/.
#
#	Version 0.1 created by Ruben Rubio Rey (tk421.1 at gmail dot com)
#
###############################################
#	CONFIGURATION
###############################################
#   Pid File
$pid_file = "/var/run/sphinx_update.pl.pid"; # if you change this do it also in init.d

# Directory where we hear updates
$update_dir = "/tmp/sphinx-updates/";

#uid gid 
$user  = "www-data";
$group = "www-data";

#log 
$LOG = "/tmp/sphinx_update.log";

#   Sphinx configuration path - not needed in this version 
# $sphinx_conf_file = "/var/www/sphinx.conf";

#   Indexer binary path 
$sphinx_indexer = "/usr/local/bin/indexer";

#sphinx debug
$sphinx_debug = "--quiet";
#$sphinx_debug = "";

#We do not neet to parse conf in this version
#$sphinx_conf_content = &load_configuration( $sphinx_conf_file );

################################################################################
# You should not edit anything after this line
################################################################################
# Check that the directory what we are going to listen exists
if (! ( -d $update_dir )) {
    &debug("[+] $update_dir does not exists, creating ");
    mkdir $update_dir or die &debug("[E] Unable to create dir $update_dir due $!");
    &systemx("chown $user:$group $update_dir");
}

$pid = fork();

if ( $pid ) {
    &debug("[+] Create $pid_file pid $pid");
    open  PID, ">$pid_file" || die &debug("[E] Cannot write on $pid_file due $!");
    print PID $pid;
    close PID;
    exit 0;
}

#Main loop, we wait for data on the directory
&debug("[+] Listening at $update_dir");

while (1 == 1) {
    
    opendir ( DIR, $update_dir ) || die &debug("[E] Error in opening dir $dirname");
    
    while( ($filename = readdir(DIR))){
        
        if ( $filename eq "." || $filename eq "..") {
            next;	
        }
        
        sleep 1; #we delay the update to make sure the new data is in the databse
        
        ($main, $delta) = split (/\./, $filename);
        debug("[+] Starting live update main: $main, delta: $delta");
        
        debug("[+] Rotating $delta");
        if ( systemx("nice /usr/local/bin/indexer -c $sphinx_conf_file --rotate $sphinx_debug  $delta")=~/WARNING/ ) {
            sleep 0.1;	#delay to prevent indexer to fail
            debug("[+] Creating $delta");
            systemx("nice $sphinx_indexer -c $sphinx_conf_file $sphinx_debug $delta");
            sleep 0.1;	#delay to prevent indexer to fail
        } else {
            sleep 10; # if you don't wait, merge does not throw an error but does not work
            debug("[+] Merging and rotating $delta into $main");
            if ( systemx("nice $sphinx_indexer -c $sphinx_conf_file --rotate $sphinx_debug --merge  $main $delta") =~/FATAL/ ) {
                sleep 0.1; #delay to prevent indexer to fail
                debug("[+] Rotaing failed, just Merging $delta into $main");
                systemx("nice $sphinx_indexer -c $sphinx_conf_file $sphinx_debug --merge  $main $delta");
            }
        }

        unlink("$update_dir$filename") || die debug("[E] Cannot delete $update_dir$filename.due $! Exiting");
    }
    
    closedir(DIR);
    
    sleep 2;
}






###############################################
#	FUNCTIONS
###############################################

#sub load_configuration() { # not needed yet
#	my $sphinx_conf_content = shift; 
#	my @content;
#	
#	open FILE, $sphinx_conf_content or die "[E] Unable to open $sphinx_conf_content because $!";
#	@content = <FILE>;
#	close FILE;
#	
#	return join ("", @content);
#}

#All output uses debug function, so we could log the user actions
sub debug() {
    my $str = shift;
    if ( $str ) {
        &addtolog($str);
        #print "$str\n";
    }
}

#add to log file
sub addtolog(){
    my $str = shift;
    my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
    ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime();
    if (length($minute) == 1 ) {
        $minute = "0$minute";
    }
    if (length($second) == 1 ) {
        $second = "0$second";
    }

    $year = 1900 + $yearOffset;
    open  LOG, ">>$LOG" or die "Unable to open log file $LOG because $!";
    print LOG "$months[$month] $dayOfMonth, $year $hour:$minute:$second | $str\n";
    close LOG;	
}

#Executes a command and logs the output
sub systemx() {
    my $cmd = shift;
    $output = `$cmd  2>&1 `;
    &addtolog("{EXECUTE} $cmd");
    &debug($output);
    return $output;
}

